import random
import sys
from PyQt5.QtCore import * # type: ignore
from PyQt5.QtGui import *  # type: ignore
from PyQt5.QtWidgets import *  # type: ignore

SCREEN_WIDTH = 640

SCREEN_HEIGHT = 480
COLOR_BLACK = QColor(0, 0, 0)
COLCR_RED = QColor(255, 0, 0)
COLCR_GREEN = QColor(0, 200, 0)
NUM20=20
SCREEN_W=32
SCREEN_H=24
DIR_UP   = ( 0, -1)
DIR_DOWN = ( 0,  1)
DIR_LEFT = (-1,  0)
DIR_RIGHT= ( 1,  0)
map = []
for x in range(0, SCREEN_W):     # 0, 1, 2, 3, 4 .. 31
    for y in range(0, SCREEN_H): # 0, 1, 2, 3 .. 23
        map.append([x, y])
class SnakeGame(QMainWindow):
   def __init__(self):
       super().__init__()
       #设置标题
       self.setWindowTitle('贪吃蛇游戏V1.0')
       self.setWindowIcon(QIcon("./img/icon.png"))
       #设置窗口大 
       self.setFixedSize(SCREEN_WIDTH,SCREEN_HEIGHT)
       self.frame=GanmeFrame(self)
       self.setCentralWidget(self.frame)
     
#蛇类封装
class Snake:
    def __init__(self):
        self.body=[[5,4]]
        self.direction=DIR_RIGHT
        self.score=0 
        self.grow()
        self.grow()
        self.head_img = QImage("./img/head-red.png").scaled(NUM20, NUM20)
    def grow(self):
        tail_x, tail_y = self.body[-1]
        # 添加到尾部
        self.body.append([tail_x, tail_y])
            
    def move(self):
        head_x,head_y=self.body[0]  
        dir_x,dir_y=self.direction    
        new_head=[head_x+dir_x,head_y+dir_y]  
        self.body.insert(0,new_head)
        self.body.pop()
    def handle_event(self, event: QKeyEvent):
        if event.key() == Qt.Key_Up and self.direction != DIR_DOWN:
            # print("向上")
            self.direction = DIR_UP
        elif event.key() == Qt.Key_Down and self.direction != DIR_UP:
            # print("向下")
            self.direction = DIR_DOWN
        elif event.key() == Qt.Key_Left and self.direction != DIR_RIGHT:
            # print("向左")
            self.direction = DIR_LEFT
        elif event.key() == Qt.Key_Right and self.direction != DIR_LEFT:
            # print("向右")
            self.direction = DIR_RIGHT    
    def draw(self,painter:QPainter):
        head_x,head_y=self.body[0]
        painter.drawImage(head_x*NUM20,head_y*NUM20,self.head_img)
        for x,y in self.body[1:]:
            painter.drawRect(x*NUM20,y*NUM20,NUM20,NUM20)    
#食物类封装
class Food:
    def __init__(self,snake:Snake):
        self.pos = self.generate_food(snake)
    def generate_food(self, snake: Snake):
        # return [random.randint(0, 31), random.randint(0, 23)]  # [31, 23]
        # 通过推导式，得到新的temp_map，只保留蛇身以外的所有坐标
        temp_map = [node for node in map if node not in snake.body]
        
        if len(temp_map) == 0:
            return
        
        # 生成新的坐标
        node = random.choice(temp_map)
        print("food: ", node)
        return node
            
    def draw(self,painter:QPainter):
        painter.setBrush(COLCR_RED) # Red, Green, Blue
        painter.drawRect(self.pos[0] * NUM20, self.pos[1] * NUM20, NUM20, NUM20)                      # type: ignore
class GanmeFrame(QFrame):
    def __init__(self,parent:QWidget):
             super().__init__(parent)
             self.game_Init()
             #开启定时器,隔200毫秒触发一次  
             self.timer=QTimer(self)
             self.timer.timeout.connect(self.update_game)
             self.timer.start(200)       
             self.setFocusPolicy(Qt.StrongFocus) 
             self.bg_img = QImage("./img/bg.png").scaled(SCREEN_WIDTH, SCREEN_HEIGHT)
    def game_Init(self):
           self.snake=Snake()  #实例化self
           self.food=Food(self.snake)
           
         
    def update_game(self):
        self.snake.move()   
        head=self.snake.body[0] 
        new_head_x,new_head_y=head
        if (head in self.snake.body[1:]
             or new_head_x < 0 or new_head_x >= SCREEN_W
             or new_head_y < 0 or new_head_y >= SCREEN_H):
           print("游戏结束")
           QMessageBox.information(self, '游戏结束', f"得分是{self.snake.score},"'你输了！')
           self.game_Init()
        if head == self.food.pos:
            self.snake.grow()
            self.food = Food(self.snake) 
            self.snake.score += 1 
        self.update()
    def keyPressEvent(self, event:QKeyEvent):
       self.snake.handle_event(event)
    def paintEvent(self, event:QPaintEvent):
        #绘制背景
        painter=QPainter(self)  
        
        # 画笔设置抗锯齿
        painter.setRenderHint(QPainter.Antialiasing, True)
        # 绘制背景图片
        painter.drawImage(0, 0, self.bg_img)
         
      
       
        painter.setBrush(COLCR_RED) 
        self.food.draw(painter)
        #绘制蛇
        painter.setBrush(COLCR_GREEN) 
        self.snake.draw(painter) 
        
if __name__ == '__main__':
    app=QApplication(sys.argv)
    #创建窗口
    game=SnakeGame()
    game.show()
    sys.exit(app.exec_())
